﻿namespace DomainServices.Tools
{
    using Microsoft.Build.Framework;
    using Microsoft.Build.Utilities;
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Globalization;
    using System.IO;
    using System.Linq;
    using System.Runtime.CompilerServices;
    using System.Text;
    using System.Web.Compilation;
    using System.Web.Hosting;

    public class CreateRiaClientFilesTask : RiaClientFilesTask
    {
        private IEnumerable<string> _clientAssemblyPathsNormalized;
        private IEnumerable<string> _clientReferenceAssembliesNormalized;
        private List<ITaskItem> _copiedFiles = new List<ITaskItem>();
        private List<ITaskItem> _generatedFiles = new List<ITaskItem>();
        private IEnumerable<string> _linkedFilesNormalized;
        private DomainServices.Tools.LinkedServerProjectCache _linkedServerProjectCache;
        private DomainServices.Tools.ProjectFileReader _projectFileReader;
        private string _serverOutputPath;
        private string _serverProjectDirectory;
        private ProjectSourceFileCache _serverProjectSourceFileCache;
        private string _serverRootNamespace;
        private Dictionary<string, IList<string>> _sharedFilesByProject;

        private void AddCopiedFile(string fileName)
        {
            this._copiedFiles.Add(new TaskItem(fileName));
        }

        private void AddGeneratedFile(string fileName)
        {
            this._generatedFiles.Add(new TaskItem(fileName));
        }

        private static string ComposeDestinationPath(string sourceFilePath, DirectoryInfo sourceDirectory, DirectoryInfo destinationDirectory)
        {
            DirectoryInfo sourceFileDirectory = new DirectoryInfo(Path.GetDirectoryName(sourceFilePath));
            IEnumerable<string> subfolders = GetSubfolders(sourceDirectory, sourceFileDirectory);
            string fullName = destinationDirectory.FullName;
            foreach (string str2 in subfolders)
            {
                fullName = Path.Combine(fullName, str2);
            }
            return Path.Combine(fullName, Path.GetFileName(sourceFilePath));
        }

        private bool CopyFile(string sourceFilePath, DirectoryInfo sourceDirectory, DirectoryInfo destinationDirectory)
        {
            string path = ComposeDestinationPath(sourceFilePath, sourceDirectory, destinationDirectory);
            string directoryName = Path.GetDirectoryName(path);
            if (!base.SafeFolderCreate(directoryName))
            {
                return false;
            }
            this.AddCopiedFile(path);
            if (base.IsFileWriteTimeDifferent(sourceFilePath, path))
            {
                base.LogMessage(string.Format(CultureInfo.CurrentCulture, Resource.ClientCodeGen_Copying_File, new object[] { sourceFilePath, destinationDirectory.FullName }));
                base.SafeFileCopy(sourceFilePath, path, true);
                return true;
            }
            base.LogMessage(string.Format(CultureInfo.CurrentCulture, Resource.ClientCodeGen_Skipping_Copy, new object[] { path }));
            return false;
        }

        private void CopySharedFiles()
        {
            Dictionary<string, IList<string>> sharedFilesByProject = this.SharedFilesByProject;
            HashSet<string> set = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
            foreach (string str in sharedFilesByProject.Keys)
            {
                string directoryName = Path.GetDirectoryName(str);
                DirectoryInfo sourceDirectory = new DirectoryInfo(directoryName);
                string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(str);
                bool flag = string.Equals(directoryName, this.ServerProjectDirectory, StringComparison.OrdinalIgnoreCase);
                IEnumerable<string> enumerable = sharedFilesByProject[str];
                foreach (string str4 in enumerable)
                {
                    if (!set.Contains(str4))
                    {
                        string generatedCodePath = base.GeneratedCodePath;
                        string path = flag ? generatedCodePath : Path.Combine(generatedCodePath, fileNameWithoutExtension);
                        DirectoryInfo destinationDirectory = new DirectoryInfo(path);
                        this.CopyFile(str4, sourceDirectory, destinationDirectory);
                        set.Add(str4);
                    }
                }
            }
        }

        private SharedCodeServiceParameters CreateSharedCodeServiceParameters(IEnumerable<string> serverAssemblies)
        {
            SharedCodeServiceParameters parameters = new SharedCodeServiceParameters {
                ServerAssemblies = serverAssemblies.ToArray<string>(),
                SharedSourceFiles = this.GetSharedAndLinkedFiles().ToArray<string>()
            };
            if (parameters.SharedSourceFiles.Any<string>())
            {
                StringBuilder builder = new StringBuilder();
                foreach (string str in parameters.SharedSourceFiles)
                {
                    builder.AppendLine();
                    builder.Append("    " + str);
                }
                base.LogMessage(string.Format(CultureInfo.CurrentCulture, Resource.CodeGen_Shared_Files, new object[] { builder.ToString() }));
            }
            parameters.ClientAssemblies = this.NormalizedTaskItems(this.ClientReferenceAssemblies, base.ClientProjectDirectory).ToArray<string>();
            parameters.ClientAssemblyPathsNormalized = this.ClientAssemblyPathsNormalized.ToArray<string>();
            parameters.SymbolSearchPaths = (from a in serverAssemblies select Path.GetDirectoryName(a)).ToArray<string>();
            return parameters;
        }

        private void DeleteCodeGenMetafilesIfInvalid()
        {
            string str = base.FileListPath();
            if (!string.IsNullOrEmpty(str) && File.Exists(str))
            {
                bool flag = false;
                using (StreamReader reader = new StreamReader(str))
                {
                    string str2;
                    if (((str2 = reader.ReadLine()) != null) && (string.IsNullOrEmpty(str2) || !string.Equals(str2, base.ClientProjectDirectory, StringComparison.OrdinalIgnoreCase)))
                    {
                        flag = true;
                    }
                }
                if (flag)
                {
                    base.DeleteCodeGenMetafileLists();
                }
            }
        }

        private bool EnsureAssembliesExist(IEnumerable<string> assemblies)
        {
            foreach (string str in assemblies)
            {
                if (!File.Exists(str))
                {
                    base.LogWarning(string.Format(CultureInfo.CurrentCulture, Resource.ClientCodeGen_Input_Assembly_Not_Found, new object[] { str }));
                    return false;
                }
            }
            return true;
        }

        protected override bool ExecuteInternal()
        {
            this._generatedFiles.Clear();
            this._copiedFiles.Clear();
            this._sharedFilesByProject = null;
            this._linkedFilesNormalized = null;
            this._serverProjectDirectory = null;
            this._clientAssemblyPathsNormalized = null;
            this._clientReferenceAssembliesNormalized = null;
            this._serverOutputPath = null;
            try
            {
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
                base.LogMessage(string.Format(CultureInfo.CurrentCulture, Resource.CodeGen_Generating_Proxies, new object[] { Path.GetFileName(base.ClientProjectPath) }));
                this.DeleteCodeGenMetafilesIfInvalid();
                if (this.IsServerProjectAvailable)
                {
                    this.CopySharedFiles();
                    this.GenerateClientProxies();
                }
                this.PurgeOrphanFiles();
                this.WriteFileList();
                if (!this.ServerProjectSourceFileCache.IsFileCacheCurrent && base.SafeFolderCreate(Path.GetDirectoryName(base.SourceFileListPath())))
                {
                    this.ServerProjectSourceFileCache.SaveCacheToFile();
                }
                if (!this.LinkedServerProjectCache.IsFileCacheCurrent && base.SafeFolderCreate(Path.GetDirectoryName(base.LinkedServerProjectsPath())))
                {
                    this.LinkedServerProjectCache.SaveCacheToFile();
                }
                double num = ((double) stopwatch.ElapsedMilliseconds) / 1000.0;
                string message = string.Format(CultureInfo.CurrentCulture, Resource.CodeGen_Execution_Time, new object[] { num });
                base.LogMessage(message);
            }
            finally
            {
                this.ReleaseResources();
            }
            return !base.HasLoggedErrors;
        }

        internal void GenerateClientProxies()
        {
            IEnumerable<string> serverAssemblies = this.GetServerAssemblies();
            IEnumerable<string> referenceAssemblies = this.GetReferenceAssemblies();
            IEnumerable<string> references = serverAssemblies.Concat<string>(referenceAssemblies);
            if (this.EnsureAssembliesExist(referenceAssemblies))
            {
                string str = serverAssemblies.FirstOrDefault<string>();
                if (string.IsNullOrEmpty(str) || !File.Exists(str))
                {
                    string fileName = Path.GetFileName(this.ServerProjectPath);
                    base.LogWarning(string.Format(CultureInfo.CurrentCulture, Resource.ClientCodeGen_No_Input_Assemblies, new object[] { fileName }));
                }
                else
                {
                    string str3 = Path.Combine(base.GeneratedCodePath, this.GenerateProxyFileName(str));
                    bool flag = this.HaveReferencesChanged(base.ServerReferenceListPath(), references, this.ServerProjectDirectory);
                    bool flag2 = this.HaveReferencesChanged(base.ClientReferenceListPath(), this.ClientReferenceAssembliesNormalized, base.ClientProjectDirectory);
                    bool flag3 = flag || flag2;
                    if (!flag3)
                    {
                        FileInfo info = new FileInfo(str3);
                        bool exists = info.Exists;
                        flag3 = !exists || (info.Length == 0L);
                        if ((!flag3 && exists) && (File.Exists(base.ServerReferenceListPath()) && (File.GetLastWriteTime(str3) > File.GetLastWriteTime(base.ServerReferenceListPath()))))
                        {
                            flag3 = true;
                            flag = true;
                        }
                    }
                    if (flag3)
                    {
                        this.WarnIfNoPdb(str);
                        string str4 = string.Empty;
                        ClientBuildManagerParameter parameter2 = new ClientBuildManagerParameter {
                            PrecompilationFlags = PrecompilationFlags.ForceDebug
                        };
                        ClientBuildManagerParameter parameter = parameter2;
                        string serverProjectDirectory = this.ServerProjectDirectory;
                        string appPhysicalTargetDir = null;
                        using (ClientBuildManager manager = new ClientBuildManager("/", serverProjectDirectory, appPhysicalTargetDir, parameter))
                        {
                            string[] strArray = references.ToArray<string>();
                            ClientCodeGenerationOptions options2 = new ClientCodeGenerationOptions {
                                Language = this.Language,
                                ClientFrameworkPath = this.ClientFrameworkPath,
                                ClientRootNamespace = this.ClientProjectRootNamespace,
                                ServerRootNamespace = this.ServerProjectRootNameSpace,
                                ClientProjectPath = base.ClientProjectPath,
                                ServerProjectPath = this.ServerProjectPath,
                                IsApplicationContextGenerationEnabled = this.IsClientApplicationAsBool,
                                UseFullTypeNames = this.UseFullTypeNamesAsBool
                            };
                            ClientCodeGenerationOptions options = options2;
                            CrossAppDomainLogger loggingService = new CrossAppDomainLogger(this);
                            SharedCodeServiceParameters parameters = this.CreateSharedCodeServiceParameters(strArray);
                            if (HostingEnvironment.InitializationException != null)
                            {
                                throw new InvalidOperationException(Resource.HttpRuntimeInitializationError, HostingEnvironment.InitializationException);
                            }
                            using (ClientCodeGenerationDispatcher dispatcher = (ClientCodeGenerationDispatcher) manager.CreateObject(typeof(ClientCodeGenerationDispatcher), false))
                            {
                                str4 = dispatcher.GenerateCode(options, parameters, loggingService, this.CodeGeneratorName);
                            }
                        }
                        if (!string.IsNullOrEmpty(str4))
                        {
                            base.LogMessage(string.Format(CultureInfo.CurrentCulture, Resource.Writing_Generated_Code, new object[] { str3 }));
                        }
                        base.WriteOrDeleteFileToVS(str3, str4, false);
                    }
                    else
                    {
                        base.LogMessage(string.Format(CultureInfo.CurrentCulture, Resource.ClientCodeGen_Skipping_CodeGen, new object[] { str3 }));
                    }
                    if (File.Exists(str3))
                    {
                        this.AddGeneratedFile(str3);
                    }
                    if (flag)
                    {
                        this.WriteReferenceList(base.ServerReferenceListPath(), references, this.ServerProjectDirectory);
                    }
                    if (flag2)
                    {
                        this.WriteReferenceList(base.ClientReferenceListPath(), this.ClientReferenceAssembliesNormalized, base.ClientProjectDirectory);
                    }
                }
            }
        }

        private string GenerateProxyFileName(string serverAssemblyName)
        {
            StringBuilder builder = new StringBuilder();
            if (serverAssemblyName == null)
            {
                builder.Append("_ClientProxies");
            }
            else
            {
                builder.Append(Path.GetFileNameWithoutExtension(serverAssemblyName));
            }
            builder.Append(".g.");
            builder.Append(this.FileExtension);
            return builder.ToString();
        }

        private IEnumerable<string> GetReferenceAssemblies()
        {
            List<string> list = new List<string>();
            if (this.ServerReferenceAssemblies != null)
            {
                foreach (ITaskItem item in this.ServerReferenceAssemblies)
                {
                    string itemSpec = item.ItemSpec;
                    if (!Path.IsPathRooted(itemSpec))
                    {
                        itemSpec = Path.GetFullPath(Path.Combine(base.ClientProjectDirectory, itemSpec));
                    }
                    list.Add(itemSpec);
                }
            }
            return list;
        }

        private IEnumerable<string> GetServerAssemblies()
        {
            List<string> list = new List<string>();
            foreach (ITaskItem item in this.ServerAssemblies)
            {
                string itemSpec = item.ItemSpec;
                if (!Path.IsPathRooted(itemSpec))
                {
                    itemSpec = Path.GetFullPath(Path.Combine(base.ClientProjectDirectory, itemSpec));
                }
                list.Add(itemSpec);
            }
            return list;
        }

        internal IEnumerable<string> GetSharedAndLinkedFiles()
        {
            IList<string> first = new List<string>(from f in this.ServerProjectSourceFileCache.GetSourceFilesInAllProjects()
                where IsFileShared(f)
                select f);
            IEnumerable<string> linkedFilesNormalized = this.LinkedFilesNormalized;
            return first.Concat<string>(linkedFilesNormalized);
        }

        private Dictionary<string, IList<string>> GetSharedFilesByProject()
        {
            Dictionary<string, IList<string>> dictionary = new Dictionary<string, IList<string>>();
            HashSet<string> set = new HashSet<string>(this.LinkedServerProjectCache.LinkedServerProjects, StringComparer.OrdinalIgnoreCase);
            foreach (string str in this.ServerProjectSourceFileCache.GetAllKnownProjects())
            {
                bool flag = false;
                bool flag2 = false;
                foreach (string str2 in this.ServerProjectSourceFileCache.GetSourceFilesInProject(str))
                {
                    if ((!flag2 && IsFileShared(str2)) && File.Exists(str2))
                    {
                        if (!flag)
                        {
                            flag = true;
                            if (set.Contains(str))
                            {
                                string str3 = this.LinkedServerProjectCache.GetLinkedServerProjectSources(str).FirstOrDefault<string>();
                                base.LogMessage(string.Format(CultureInfo.CurrentCulture, Resource.RIA_Link_Prevents_Copy, new object[] { str, str3 }));
                                flag2 = true;
                                continue;
                            }
                        }
                        IList<string> list = null;
                        if (!dictionary.TryGetValue(str, out list))
                        {
                            dictionary[str] = list = new List<string>();
                        }
                        list.Add(str2);
                    }
                }
            }
            return dictionary;
        }

        private static IList<string> GetSubfolders(DirectoryInfo sourceDirectory, DirectoryInfo sourceFileDirectory)
        {
            List<string> list = new List<string>();
            while (!sourceFileDirectory.FullName.Equals(sourceDirectory.FullName))
            {
                list.Insert(0, sourceFileDirectory.Name);
                sourceFileDirectory = sourceFileDirectory.Parent;
                if (sourceFileDirectory == null)
                {
                    return new List<string>();
                }
            }
            return list;
        }

        private bool HaveReferencesChanged(string fileName, IEnumerable<string> references, string projectDir)
        {
            if (!File.Exists(fileName))
            {
                return true;
            }
            Dictionary<string, string> dictionary = this.ReadReferenceList(fileName, projectDir);
            foreach (string str in dictionary.Keys)
            {
                if (!references.Contains<string>(str, StringComparer.OrdinalIgnoreCase))
                {
                    return true;
                }
            }
            foreach (string str2 in references)
            {
                if (!File.Exists(str2))
                {
                    return true;
                }
                string str3 = null;
                if (!dictionary.TryGetValue(str2, out str3))
                {
                    return true;
                }
                if (!string.Format(CultureInfo.InvariantCulture, "{0}", new object[] { File.GetLastWriteTime(str2) }).Equals(str3, StringComparison.OrdinalIgnoreCase))
                {
                    return true;
                }
            }
            return false;
        }

        private static bool IsFileShared(string fileName)
        {
            return Path.GetFileNameWithoutExtension(fileName).EndsWith(".shared", StringComparison.OrdinalIgnoreCase);
        }

        private IEnumerable<string> NormalizedTaskItems(IEnumerable<ITaskItem> items, string directory)
        {
            if (items == null)
            {
                return new string[0];
            }
            return (from ti in items select this.GetFullPathRelativeToDirectory(ti.ItemSpec, directory));
        }

        protected override void NormalizeProjectPaths()
        {
            base.NormalizeProjectPaths();
            if (!string.IsNullOrEmpty(this.ServerProjectPath) && !Path.IsPathRooted(this.ServerProjectPath))
            {
                this.ServerProjectPath = base.GetFullPathRelativeToDirectory(this.ServerProjectPath, base.ClientProjectDirectory);
            }
            if (!this.IsServerProjectAvailable)
            {
                string fileName = Path.GetFileName(base.ClientProjectPath);
                base.LogError(string.Format(CultureInfo.CurrentCulture, Resource.Server_Project_File_Does_Not_Exist, new object[] { fileName, this.ServerProjectPath }));
            }
        }

        private void PurgeOrphanFiles()
        {
            IEnumerable<string> enumerable = base.FilesPreviouslyWritten();
            IEnumerable<ITaskItem> outputFiles = this.OutputFiles;
            using (IEnumerator<string> enumerator = enumerable.GetEnumerator())
            {
                System.Func<ITaskItem, bool> func = null;
                string fileName;
                while (enumerator.MoveNext())
                {
                    fileName = enumerator.Current;
                    if (File.Exists(fileName))
                    {
                        if (func == null)
                        {
                            func = i => string.Equals(fileName, i.ItemSpec, StringComparison.OrdinalIgnoreCase);
                        }
                        if (!Enumerable.Any<ITaskItem>(outputFiles, func))
                        {
                            base.LogMessage(string.Format(CultureInfo.CurrentCulture, Resource.ClientCodeGen_Deleting_Orphan, new object[] { fileName }));
                            base.DeleteFileFromVS(fileName);
                            base.DeleteFolderIfEmpty(Path.GetDirectoryName(fileName));
                        }
                    }
                    else
                    {
                        base.DeleteFolderIfEmpty(Path.GetDirectoryName(fileName));
                    }
                }
            }
        }

        private Dictionary<string, string> ReadReferenceList(string fileName, string projectDir)
        {
            Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
            if (File.Exists(fileName))
            {
                string[] strArray = File.ReadAllText(fileName).Split(new char[] { ',', ';' });
                for (int i = 0; i < strArray.Length; i++)
                {
                    if (string.IsNullOrEmpty(strArray[i]))
                    {
                        return dictionary;
                    }
                    string fullPathRelativeToDirectory = base.GetFullPathRelativeToDirectory(strArray[i], projectDir);
                    string str3 = strArray[++i];
                    dictionary[fullPathRelativeToDirectory] = str3;
                }
            }
            return dictionary;
        }

        private void ReleaseResources()
        {
            this._linkedServerProjectCache = null;
            this._serverProjectSourceFileCache = null;
            if (this._projectFileReader != null)
            {
                this._projectFileReader.Dispose();
                this._projectFileReader = null;
            }
        }

        private void WarnIfNoPdb(string assemblyFile)
        {
            if (File.Exists(assemblyFile) && !File.Exists(Path.ChangeExtension(assemblyFile, "pdb")))
            {
                base.LogWarning(string.Format(CultureInfo.CurrentCulture, Resource.CodeGen_No_Pdb, new object[] { assemblyFile }));
            }
        }

        private void WriteFileList()
        {
            StringBuilder builder = new StringBuilder();
            StringBuilder builder2 = new StringBuilder();
            builder.AppendLine(base.ClientProjectDirectory);
            foreach (ITaskItem item in this.OutputFiles)
            {
                string pathRelativeToProjectDirectory = RiaClientFilesTask.GetPathRelativeToProjectDirectory(item.ItemSpec, base.ClientProjectDirectory);
                builder.AppendLine(pathRelativeToProjectDirectory);
                builder2.AppendLine();
                builder2.Append("    " + item.ItemSpec);
            }
            string contents = builder.ToString();
            if (contents.Length > 0)
            {
                base.LogMessage(string.Format(CultureInfo.CurrentCulture, Resource.ClientCodeGen_OutputFiles_Are, new object[] { builder2.ToString() }));
            }
            string str3 = base.FileListPath();
            if ((base.FilesWereWritten && !string.IsNullOrEmpty(str3)) && base.SafeFolderCreate(Path.GetDirectoryName(str3)))
            {
                base.SafeFileWrite(str3, contents);
            }
        }

        private void WriteReferenceList(string fileName, IEnumerable<string> references, string projectDir)
        {
            StringBuilder builder = new StringBuilder();
            foreach (string str in references)
            {
                if (File.Exists(str))
                {
                    string pathRelativeToProjectDirectory = RiaClientFilesTask.GetPathRelativeToProjectDirectory(str, projectDir);
                    builder.Append(pathRelativeToProjectDirectory + "," + string.Format(CultureInfo.InvariantCulture, "{0}", new object[] { File.GetLastWriteTime(pathRelativeToProjectDirectory) }) + ";");
                }
            }
            string contents = builder.ToString();
            if (!string.IsNullOrEmpty(fileName) && base.SafeFolderCreate(Path.GetDirectoryName(fileName)))
            {
                base.SafeFileWrite(fileName, contents);
            }
        }

        internal IEnumerable<string> ClientAssemblyPathsNormalized
        {
            get
            {
                if (this._clientAssemblyPathsNormalized == null)
                {
                    ITaskItem[] clientAssemblySearchPaths = this.ClientAssemblySearchPaths;
                    this._clientAssemblyPathsNormalized = (clientAssemblySearchPaths == null) ? ((IEnumerable<string>) new string[0]) : this.NormalizedTaskItems(clientAssemblySearchPaths, base.ClientProjectDirectory);
                }
                return this._clientAssemblyPathsNormalized;
            }
        }

        [Required]
        public ITaskItem[] ClientAssemblySearchPaths { get; set; }

        [Required]
        public string ClientFrameworkPath { get; set; }

        public string ClientProjectRootNamespace { get; set; }

        [Required]
        public ITaskItem[] ClientReferenceAssemblies { get; set; }

        internal IEnumerable<string> ClientReferenceAssembliesNormalized
        {
            get
            {
                if (this._clientReferenceAssembliesNormalized == null)
                {
                    IEnumerable<string> source = this.NormalizedTaskItems(this.ClientReferenceAssemblies, base.ClientProjectDirectory);
                    this._clientReferenceAssembliesNormalized = (from f in source.Distinct<string>(StringComparer.OrdinalIgnoreCase)
                        where File.Exists(f)
                        select f).ToArray<string>();
                }
                return this._clientReferenceAssembliesNormalized;
            }
        }

        [Required]
        public ITaskItem[] ClientSourceFiles { get; set; }

        public string CodeGeneratorName { get; set; }

        [Output]
        public ITaskItem[] CopiedFiles
        {
            get
            {
                return this._copiedFiles.ToArray();
            }
        }

        private string FileExtension
        {
            get
            {
                if (!this.Language.Equals("C#", StringComparison.OrdinalIgnoreCase))
                {
                    return "vb";
                }
                return "cs";
            }
        }

        [Output]
        public ITaskItem[] GeneratedFiles
        {
            get
            {
                return this._generatedFiles.ToArray();
            }
        }

        public string IsClientApplication { get; set; }

        internal bool IsClientApplicationAsBool
        {
            get
            {
                bool flag;
                string isClientApplication = this.IsClientApplication;
                return ((!string.IsNullOrEmpty(isClientApplication) && bool.TryParse(isClientApplication, out flag)) && flag);
            }
        }

        internal bool IsServerProjectAvailable
        {
            get
            {
                string serverProjectPath = this.ServerProjectPath;
                return (!string.IsNullOrEmpty(serverProjectPath) && File.Exists(serverProjectPath));
            }
        }

        [Required]
        public string Language { get; set; }

        [Output]
        public ITaskItem[] LinkedFiles
        {
            get
            {
                return (from f in this.LinkedFilesNormalized select new TaskItem(f)).ToArray<ITaskItem>();
            }
        }

        internal IEnumerable<string> LinkedFilesNormalized
        {
            get
            {
                if (this._linkedFilesNormalized == null)
                {
                    IEnumerable<string> sourceFilesInAllProjects = this.ServerProjectSourceFileCache.GetSourceFilesInAllProjects();
                    this._linkedFilesNormalized = this.NormalizedTaskItems(this.ClientSourceFiles, base.ClientProjectDirectory).Intersect<string>(sourceFilesInAllProjects, StringComparer.OrdinalIgnoreCase);
                }
                return this._linkedFilesNormalized;
            }
        }

        internal DomainServices.Tools.LinkedServerProjectCache LinkedServerProjectCache
        {
            get
            {
                if (this._linkedServerProjectCache == null)
                {
                    this._linkedServerProjectCache = new DomainServices.Tools.LinkedServerProjectCache(base.ClientProjectPath, base.LinkedServerProjectsPath(), this, this.ProjectFileReader);
                }
                return this._linkedServerProjectCache;
            }
        }

        internal IEnumerable<ITaskItem> OutputFiles
        {
            get
            {
                return this.GeneratedFiles.Concat<ITaskItem>(this.CopiedFiles);
            }
        }

        private DomainServices.Tools.ProjectFileReader ProjectFileReader
        {
            get
            {
                if (this._projectFileReader == null)
                {
                    this._projectFileReader = new DomainServices.Tools.ProjectFileReader(this);
                }
                return this._projectFileReader;
            }
        }

        [Required]
        public ITaskItem[] ServerAssemblies { get; set; }

        internal string ServerOutputPath
        {
            get
            {
                if (this._serverOutputPath == null)
                {
                    string propertyValue = this.ProjectFileReader.GetPropertyValue(this.ServerProjectPath, "OutputPath");
                    this._serverOutputPath = base.GetFullPathRelativeToDirectory(propertyValue, this.ServerProjectDirectory);
                }
                return this._serverOutputPath;
            }
        }

        private string ServerProjectDirectory
        {
            get
            {
                if (this._serverProjectDirectory == null)
                {
                    if (this.ServerProjectPath == null)
                    {
                        base.LogError(string.Format(CultureInfo.CurrentCulture, Resource.ProjectPath_Argument_Required, new object[] { "ServerProjectPath" }));
                        return string.Empty;
                    }
                    this._serverProjectDirectory = Path.GetDirectoryName(base.GetFullPathRelativeToDirectory(this.ServerProjectPath, base.ClientProjectDirectory));
                }
                return this._serverProjectDirectory;
            }
        }

        [Required]
        public string ServerProjectPath { get; set; }

        internal string ServerProjectRootNameSpace
        {
            get
            {
                if (this._serverRootNamespace == null)
                {
                    this._serverRootNamespace = this.ProjectFileReader.GetPropertyValue(this.ServerProjectPath, "RootNamespace");
                }
                return this._serverRootNamespace;
            }
        }

        internal ProjectSourceFileCache ServerProjectSourceFileCache
        {
            get
            {
                if (this._serverProjectSourceFileCache == null)
                {
                    this._serverProjectSourceFileCache = new ProjectSourceFileCache(this.ServerProjectPath, base.SourceFileListPath(), this, this.ProjectFileReader);
                }
                return this._serverProjectSourceFileCache;
            }
        }

        [Required]
        public ITaskItem[] ServerReferenceAssemblies { get; set; }

        [Output]
        public ITaskItem[] SharedFiles
        {
            get
            {
                Dictionary<string, IList<string>> sharedFilesByProject = this.SharedFilesByProject;
                List<ITaskItem> list = new List<ITaskItem>();
                foreach (IList<string> list2 in sharedFilesByProject.Values)
                {
                    foreach (string str in list2)
                    {
                        list.Add(new TaskItem(str));
                    }
                }
                return list.ToArray();
            }
        }

        internal Dictionary<string, IList<string>> SharedFilesByProject
        {
            get
            {
                if (this._sharedFilesByProject == null)
                {
                    this._sharedFilesByProject = this.GetSharedFilesByProject();
                }
                return this._sharedFilesByProject;
            }
        }

        public string UseFullTypeNames { get; set; }

        internal bool UseFullTypeNamesAsBool
        {
            get
            {
                bool flag;
                string useFullTypeNames = this.UseFullTypeNames;
                return ((!string.IsNullOrEmpty(useFullTypeNames) && bool.TryParse(useFullTypeNames, out flag)) && flag);
            }
        }

        internal class CrossAppDomainLogger : MarshalByRefObject, ILoggingService, DomainServices.Tools.ILogger
        {
            private ILoggingService baseLogger;

            public CrossAppDomainLogger(ILoggingService underlyingLogger)
            {
                this.baseLogger = underlyingLogger;
            }

            public void LogError(string message)
            {
                this.baseLogger.LogError(message);
            }

            public void LogError(string message, string subCategory, string errorCode, string helpKeyword, string file, int lineNumber, int columnNumber, int endLineNumber, int endColumnNumber)
            {
                this.baseLogger.LogError(message, subCategory, errorCode, helpKeyword, file, lineNumber, columnNumber, endLineNumber, endColumnNumber);
            }

            public void LogMessage(string message)
            {
                this.baseLogger.LogMessage(message);
            }

            public void LogWarning(string message)
            {
                this.baseLogger.LogWarning(message);
            }

            public void LogWarning(string message, string subCategory, string errorCode, string helpKeyword, string file, int lineNumber, int columnNumber, int endLineNumber, int endColumnNumber)
            {
                this.baseLogger.LogWarning(message, subCategory, errorCode, helpKeyword, file, lineNumber, columnNumber, endLineNumber, endColumnNumber);
            }

            public bool HasLoggedErrors
            {
                get
                {
                    return this.baseLogger.HasLoggedErrors;
                }
            }
        }
    }
}

